<template>
  <div>
    <el-dialog
      title="设计工艺路线"
      :visible.sync="dialogVisible"
      :modal="true"
      :appendToBody="true"
      width="95%"
      :close-on-click-modal="false"
      top="5vh"
      v-dialog-drag
      @close="handleClose()"
      @open="handleOpen()"
    >
      <div v-loading="loading" class="design-dialog-content">
        <el-form
          :model="form"
          ref="ruleForm"
          label-width="120px"
          class="top-form"
        >
          <el-row :gutter="10">
            <el-col :span="6">
              <el-form-item label="工艺路线编码" prop="processRouteCode">
                {{ form.processRouteCode }}
              </el-form-item>
            </el-col>
            <el-col :span="6">
              <el-form-item label="工艺路线名称" prop="processRouteName">
                {{ form.processRouteName }}
              </el-form-item>
            </el-col>
            <el-col :span="6">
              <el-form-item label="所属工厂" prop="factoryDeptName">
                {{ form.factoryDeptName }}
              </el-form-item>
            </el-col>
            <el-col :span="6">
              <el-form-item label="所属车间" prop="workshopName">
                {{ form.workshopName }}
              </el-form-item>
            </el-col>
          </el-row>
          <el-row :gutter="10">
            <el-col :span="6">
              <el-form-item label="所属产线" prop="lineName">
                {{ form.lineName }}
              </el-form-item>
            </el-col>
            <el-col :span="6">
              <el-form-item label="所属产品" prop="itemName">
                {{ form.itemName }}
              </el-form-item>
            </el-col>
          </el-row>
        </el-form>
        <div class="process-content">
          <el-button
            type="primary"
            size="small"
            class="citing-btn"
            @click="handleCopyOpen"
            >引用</el-button
          >
          <Process
            ref="Process"
            :form="form"
            :processRouteData="processRouteData"
          ></Process>
        </div>
      </div>
      <span slot="footer" class="dialog-footer">
        <el-button @click="dialogVisible = false">取 消</el-button>
        <el-button type="primary" :loading="saveloading" @click="handleSubmit"
          >确 定</el-button
        >
      </span>
    </el-dialog>
    <!-- 工艺路线列表 -->
    <ProcessRouteList
      :visible.sync="processRouteDialog.visible"
      :multiple="false"
      :disabledSearch="{
        factory: true,
        workshop: true,
        line: true,
        searchValue: false,
      }"
      :defaultSearch="{
        factoryDeptCode: form.factoryDeptCode,
        workshopId: form.workshopId,
        workshopCode: form.workshopCode,
        lineId: form.lineId,
      }"
      @closeDialog="handleCloseProcessRoute"
    ></ProcessRouteList>
  </div>
</template>
<script>
import {
  saveProcessRouteChart,
  getProcessRouteChart,
} from "@/api/processRouteMgmt/maintenance";
import Process from "./process/index";
import ProcessRouteList from "@/views/components/processRouteList";
export default {
  components: { Process, ProcessRouteList },
  props: {
    visible: {
      type: Boolean,
      default: false,
    },
    row: {
      type: Object,
      default: null,
    },
  },
  data() {
    return {
      loading: false,
      form: {},
      processRouteData: null,
      saveloading: false,
      processRouteDialog: {
        visible: false,
      },
    };
  },
  computed: {
    dialogVisible: {
      set(val) {
        this.$emit("update:visible", val);
      },
      get() {
        return this.visible;
      },
    },
  },
  methods: {
    handleClose() {
      this.form = {};
      this.processRouteData = null;
    },
    handleOpen() {
      this.getProcessRouteChartData();
    },
    // 获取工艺路线图数据
    getProcessRouteChartData() {
      if (!this.row?.id) {
        return;
      }
      this.loading = true;
      getProcessRouteChart(this.row.id)
        .then((res) => {
          if (res?.data) {
            const data = res?.data;
            this.form = data?.processRoute || {};
            this.processRouteData = {
              nodes: data.nodes || [],
              edges: data.edges || [],
            };
          }
        })
        .finally(() => {
          this.loading = false;
        });
    },
    // 点击应用按钮，打开工艺路线列表
    handleCopyOpen() {
      this.processRouteDialog.visible = true;
    },
    // 关闭工艺路线列表
    handleCloseProcessRoute(list) {
      if (!list?.length) {
        return;
      }
      this.$confirm(
        `是否确定引用${list[0].processRouteName}的工艺路线`,
        "提示",
        {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning",
        }
      ).then(() => {
        this.loading = true;
        getProcessRouteChart(list[0].id)
          .then((res) => {
            if (res?.data) {
              const data = res?.data;
              this.processRouteData = {
                nodes: data.nodes || [],
                edges: data.edges || [],
              };
            }
          })
          .finally(() => {
            this.loading = false;
          });
      });
    },
    // 提交
    handleSubmit() {
      if (!this.form.processRouteCode) {
        return;
      }
      this.saveloading = true;
      const graphData = this.$refs.Process.getGraphData();
      console.log("graphData", graphData);
      const param = {
        processRouteCode: this.form.processRouteCode,
        nodes: graphData.nodes.map((ele) => ({
          id: ele.id,
          type: ele.type,
          x: ele.x,
          y: ele.y,
          text: "",
          properties: {
            workSectionCode: ele.properties.workSectionCode || "",
            equipmentIds:
              ele.properties.equipmentList
                ?.map((equip) => equip.equipId)
                .join(",") || "",
            workStationIds:
              ele.properties.workStationList
                ?.map((equip) => equip.id)
                .join(",") || "",
          },
        })),
        edges: graphData.edges.map((ele) => ({
          id: ele.id,
          sourceNodeId: ele.sourceNodeId,
          targetNodeId: ele.targetNodeId,
          type: "polyline",
          text: "",
        })),
      };
      console.log("param", param);

      // 校验
      const flag = this.validator(graphData);
      if (!flag) {
        // 校验不通过
        this.msgError("路线不完整，请查看");
        this.saveloading = false;
        return;
      }

      saveProcessRouteChart(param)
        .then((res) => {
          if (res.code == 200) {
            this.msgSuccess("保存成功！");
            this.$emit("submit-success");
            this.dialogVisible = false;
          }
        })
        .finally(() => {
          this.saveloading = false;
        });
    },
    // 校验，必须以《开始》节点为开始，以《结束》节点为结束，不能有不连线的工序，不能有一条以上工序
    validator(graphData) {
      // 节点数据
      const nodes = [...graphData.nodes];
      // 边数据
      const edges = [...graphData.edges];
      // 已纳入寻找路线的节点id
      const nodeIds = new Set([]);
      // 已纳入寻找路线的边id
      const edgeIds = new Set([]);
      // 找出开始节点以及开始节点的线
      const startNodeIndex = nodes.findIndex((node) => (node.type = "start"));
      const startEdgeIndex = edges.findIndex(
        (edge) => edge.sourceNodeId == nodes[startNodeIndex].id
      );
      edgeIds.add(edges[startEdgeIndex].id);
      nodeIds.add(edges[startEdgeIndex].sourceNodeId);
      nodeIds.add(edges[startEdgeIndex].targetNodeId);

      // 查找关联
      const _nodeids = this.getConnect(
        [...edges],
        edges[startEdgeIndex].targetNodeId
      );
      _nodeids.forEach((id) => {
        nodeIds.add(id);
      });

      // 已在主流程中的节点数量与所有节点数量相等，说明所有节点都在主流程中
      return nodeIds.size == nodes.length;
    },
    getConnect(edges, nodeid) {
      let nodeIds = [];
      edges.forEach((edge) => {
        const _edges = edges.filter((ele) => ele.id != edge.id);
        if (edge.sourceNodeId == nodeid) {
          nodeIds.push(edge.targetNodeId);
          nodeIds = nodeIds.concat(this.getConnect(_edges, edge.targetNodeId));
        } else if (edge.targetNodeId == nodeid) {
          nodeIds.push(edge.sourceNodeId);
          nodeIds = nodeIds.concat(this.getConnect(_edges, edge.sourceNodeId));
        }
      });
      return nodeIds;
    },
  },
};
</script>
<style lang="scss" scoped>
::v-deep .el-dialog {
  .el-dialog__body {
    height: 76vh;
    max-height: 100%;
  }
  .design-dialog-content {
    width: 100%;
    height: 100%;
    display: flex;
    flex-direction: column;
  }
  .process-content {
    width: 100%;
    flex: 1;
    position: relative;
    .citing-btn {
      position: absolute;
      right: 0;
      top: -10px;
      transform: translateY(-100%);
    }
  }
}
::v-deep .top-form {
  margin-bottom: 16px;
  .el-form-item {
    margin-bottom: 0;
  }
}
</style>
